home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / ace_gpl_release / src / lib / c / window.c < prev   
Encoding:
C/C++ Source or Header  |  1998-10-04  |  10.7 KB  |  512 lines

  1. /* <<ACE>> db.lib module: Generic window functions.
  2. ** Copyright (C) 1998 David Benn
  3. ** 
  4. ** This program is free software; you can redistribute it and/or
  5. ** modify it under the terms of the GNU General Public License
  6. ** as published by the Free Software Foundation; either version 2
  7. ** of the License, or (at your option) any later version.
  8. **
  9. ** This program is distributed in the hope that it will be useful,
  10. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ** GNU General Public License for more details.
  13. **
  14. ** You should have received a copy of the GNU General Public License
  15. ** along with this program; if not, write to the Free Software
  16. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  
  18.    Author: David J Benn
  19.      Date: 5th,7th-9th,19th,24th-26th,28th,29th,31st October 1993,
  20.        1st,4th,8th,15th November 1993,
  21.        6th February 1994,
  22.        23rd,30th April 1994,
  23.        12th,24th,28th July 1994,
  24.        13th-15th,20th August 1994,
  25.        10th,11th September 1994,
  26.        3rd,4th December 1995
  27. */
  28.  
  29. #include <intuition/intuition.h>
  30. #include <intuition/intuitionbase.h>
  31. #include <exec/memory.h>
  32. #include "intuievent.h"
  33.  
  34. #define MAXWDW            17L    /* shell wdw + user-wdws 1..16 */
  35. #define CLEARED_ANY_MEM         7L
  36. #define WINDOW_OPEN_ERR        700L
  37.  
  38. /* globals */
  39. static     BOOL     first_wdw_creation=TRUE;
  40. static     USHORT     wdw_close_num=0;
  41.  
  42. /* misc. external variables */
  43. extern    ULONG    error_code;
  44.  
  45. /* screen/intuition window vs AmigaDOS window (shell/CLI) mode */
  46. extern UBYTE IntuiMode;
  47.  
  48. /* screen pointers */ 
  49. extern struct Screen *Scrn;
  50. extern struct Screen *WBScrn;
  51. extern struct Screen *Screen_list[10];    
  52.  
  53. /* Workbench Message */
  54. extern    ULONG    WBenchMsg;
  55.  
  56. /* global window info */
  57. extern    struct Window    *Wdw;
  58. extern    struct RastPort    *RPort;
  59.  
  60. extern    USHORT    Wdw_id;
  61. extern    struct    Window     *WBWdw;
  62. extern    struct    RastPort *WBRPort;
  63. extern    USHORT    fgdpen;
  64. extern    USHORT    bgpen;
  65. extern    USHORT    WBfgdpen;
  66. extern    USHORT    WBbgpen;
  67.  
  68. extern    struct    IntuitionBase *IntuitionBase;
  69.  
  70. /* turtle graphics info */
  71. extern    USHORT    tg_initx;
  72. extern    USHORT    tg_inity;
  73. extern    USHORT    tg_tx;
  74. extern    USHORT    tg_ty;
  75. extern    USHORT    tg_degs;
  76. extern    UBYTE    tg_pen;
  77.  
  78. /* window list */
  79. typedef struct wdw_list_type
  80.     {
  81.         struct  Window      *Wdw;
  82.         struct    RastPort *RPort;
  83.         USHORT    fgdpen;
  84.         USHORT    bgpen;
  85.     } WDW;
  86.  
  87. WDW Wdw_list[MAXWDW] = { 
  88. {NULL,NULL,0,0}, {NULL,NULL,0,0}, {NULL,NULL,0,0}, {NULL,NULL,0,0},
  89. {NULL,NULL,0,0}, {NULL,NULL,0,0}, {NULL,NULL,0,0}, {NULL,NULL,0,0},
  90. {NULL,NULL,0,0}, {NULL,NULL,0,0}, {NULL,NULL,0,0}, {NULL,NULL,0,0},
  91. {NULL,NULL,0,0}, {NULL,NULL,0,0}, {NULL,NULL,0,0}, {NULL,NULL,0,0},
  92. {NULL,NULL,0,0}
  93. };
  94.  
  95. struct NewWindow NewWdw =
  96. {
  97.  0,0,
  98.  0,0,                /* position & size */
  99.  
  100.  0,1,                /* detail & block pens */
  101.  
  102.  INTUITICKS |
  103.  VANILLAKEY |
  104.  MENUPICK |
  105.  GADGETUP |
  106.  ACTIVEWINDOW,            /* IDCMP Flags */
  107.  
  108.  0,                /* Flags */
  109.  
  110.  NULL,                /* first gadget */
  111.  NULL,                /* CheckMark */
  112.  NULL,                /* title */
  113.  NULL,                /* Screen */
  114.  NULL,                /* BitMap */
  115.  
  116.  -1,-1,
  117.  -1,-1,                /* minimum & maximum window size */
  118.  
  119.  0                /* screen type */
  120. };
  121.  
  122. /* prototypes */
  123. void    MakeOutputWdw();
  124.  
  125. /* external functions */
  126. extern     void    ClearMenu();
  127. extern    void    stringcopy();
  128. extern    ULONG    stringlength();
  129. extern    void    *alloc();
  130.  
  131. /* functions */
  132. void    check_for_open_window()
  133. {
  134. /* Test for the presence of an open window
  135.    on the current screen and make the highest
  136.    numbered one (the first encountered) the
  137.    current output window. This routine is called
  138.    by _closescreen in scrwin.s.
  139. */
  140. USHORT i,wdw_on_this_screen=FALSE;
  141.  
  142.     /* search for an open window on current screen */
  143.     for (i=MAXWDW-1;i>=1;i--)
  144.         if (Wdw_list[i].Wdw->WScreen == Scrn)
  145.         { 
  146.         wdw_on_this_screen = TRUE;
  147.         break;
  148.         }
  149.  
  150.     /* set new output window? */
  151.     if (wdw_on_this_screen) 
  152.     {
  153.         Wdw_id = i;
  154.         MakeOutputWdw();
  155.     }        
  156. }
  157.  
  158. USHORT    only_shell_is_active()
  159. {
  160. /* Return true or false depending upon whether
  161.    a shell is the only window open on the Wb
  162.    screen and no other ACE screens are open.
  163. */
  164. USHORT i, no_intui_wdw = TRUE;
  165.  
  166.     for (i=MAXWDW-1;i>=1;i--)
  167.         if (Wdw_list[i].Wdw) { no_intui_wdw = FALSE; break; }
  168.  
  169.     return(no_intui_wdw && WBenchMsg == NULL && Scrn == WBScrn);
  170. }
  171.  
  172. void StoreWdwInfo()
  173. {
  174. /* store information about current window */
  175.  
  176.     Wdw_list[Wdw_id].Wdw    = Wdw;
  177.     Wdw_list[Wdw_id].RPort    = RPort;
  178.     Wdw_list[Wdw_id].fgdpen    = fgdpen;    
  179.     Wdw_list[Wdw_id].bgpen     = bgpen;    
  180. }
  181.  
  182. void DeleteWdwInfo(window_id)
  183. ULONG window_id;
  184. {
  185. /* zero all window list values for current window */
  186. USHORT id;
  187.  
  188.     id = (USHORT)window_id;
  189.  
  190.     Wdw_list[id].Wdw    = 0L;
  191.     Wdw_list[id].RPort    = 0L;
  192.     Wdw_list[id].fgdpen    = 0;
  193.     Wdw_list[id].bgpen     = 0;
  194. }
  195.  
  196. void MakeOutputWdw()
  197. {
  198. /*
  199. ** Make the Wdw_id'th window the current output window
  200. ** toggling IntuiMode if necessary. 
  201. */
  202.  
  203.     Wdw    = Wdw_list[Wdw_id].Wdw;
  204.     RPort    = Wdw_list[Wdw_id].RPort;
  205.     fgdpen    = Wdw_list[Wdw_id].fgdpen;
  206.     bgpen    = Wdw_list[Wdw_id].bgpen;
  207.  
  208.     if (Scrn == WBScrn) 
  209.     {
  210.         WBWdw     = Wdw;
  211.         WBRPort = RPort;
  212.         WBfgdpen= fgdpen;
  213.         WBbgpen = bgpen;
  214.     }
  215.  
  216.     /* 
  217.     ** If shell is new current output window switch
  218.     ** off IntuiMode.
  219.     */
  220.     if (Wdw_id == 0 && WBenchMsg == NULL)
  221.         IntuiMode = 0;
  222.     else
  223.         IntuiMode = 1;
  224. }
  225.  
  226. void ChangeOutputWdw(window_id)
  227. ULONG     window_id;
  228. {
  229. /* change the current output window */
  230. USHORT id;
  231.  
  232.     id = (USHORT)window_id;
  233.  
  234.     if (id < 0 || id > MAXWDW-1) return;
  235.     
  236.     Wdw_id = id;
  237.  
  238.     if (Wdw_list[id].Wdw != NULL) MakeOutputWdw();    
  239. }
  240.  
  241. ULONG OpenWdw(screen,type,bottom,right,top,left,title,window_id)
  242. ULONG   window_id;
  243. UBYTE   *title;
  244. ULONG   left,top,right,bottom;
  245. ULONG   type,screen;
  246. {
  247. /* open an Intuition window */
  248. USHORT   width, height,id;
  249.  
  250.     /* initialise shell window info? */
  251.     if (first_wdw_creation)
  252.     {
  253.         first_wdw_creation = FALSE;
  254.  
  255.         /* shell/CLI open? */
  256.         if (WBenchMsg == NULL)
  257.         {
  258.             Wdw_list[0].Wdw        = Wdw;
  259.             Wdw_list[0].RPort    = RPort;
  260.             Wdw_list[0].fgdpen    = fgdpen;    
  261.             Wdw_list[0].bgpen     = bgpen;    
  262.         }
  263.     }
  264.  
  265.     /* valid request? */
  266.     id = (USHORT)window_id;
  267.  
  268.     if (id < 1 || id > MAXWDW-1 || Wdw_list[id].Wdw != NULL || 
  269.         right < left || bottom < top)
  270.     { 
  271.         error_code = WINDOW_OPEN_ERR;
  272.         return(NULL);
  273.     }
  274.  
  275.     Wdw = NULL;
  276.  
  277.     /* complete NewWdw structure */
  278.     width     = right - left;
  279.     height    = bottom - top;
  280.  
  281.     NewWdw.LeftEdge = (USHORT)left;
  282.     NewWdw.TopEdge     = (USHORT)top;    
  283.     NewWdw.Width      = width;
  284.     NewWdw.Height     = height;
  285.  
  286.     if (title != NULL)
  287.     {
  288.         NewWdw.Title = (UBYTE *)
  289.                     alloc(CLEARED_ANY_MEM,
  290.                       stringlength(title)+1);
  291.  
  292.         if (NewWdw.Title == NULL) 
  293.         { 
  294.             error_code = WINDOW_OPEN_ERR;
  295.             return(NULL);
  296.         }
  297.  
  298.         stringcopy(NewWdw.Title,title);
  299.     }
  300.     else
  301.         NewWdw.Title = NULL;
  302.  
  303.     /* set window type */
  304.      NewWdw.Flags = GIMMEZEROZERO | ACTIVATE;
  305.  
  306.     if (type == -1) type = 31;    /* defaults to the works */
  307.  
  308.     if (type & 1)     { NewWdw.Flags |= WINDOWSIZING; 
  309.               NewWdw.IDCMPFlags |= NEWSIZE; }
  310.  
  311.     if (type & 2)     { NewWdw.Flags |= WINDOWDRAG; }
  312.  
  313.     if (type & 4)     { NewWdw.Flags |= WINDOWDEPTH; }
  314.  
  315.     if (type & 8)     { NewWdw.Flags |= WINDOWCLOSE; 
  316.               NewWdw.IDCMPFlags |= CLOSEWINDOW; }
  317.  
  318.     if (type & 16)     
  319.         { NewWdw.Flags |= SMART_REFRESH; }
  320.     else
  321.         { NewWdw.Flags |= NOCAREREFRESH; }
  322.  
  323.     if (type & 32)  { NewWdw.Flags |= BORDERLESS; }  /* ACE only! */
  324.  
  325.     /* Workbench or custom screen? */
  326.     if (screen >= 1 && screen <= 9)
  327.     {
  328.         NewWdw.Type        = CUSTOMSCREEN;
  329.         NewWdw.Screen    = Screen_list[screen];
  330.     }
  331.     else
  332.     if (screen == 0 || screen == -1)
  333.         NewWdw.Type        = WBENCHSCREEN;
  334.     else
  335.     {
  336.         error_code = WINDOW_OPEN_ERR;
  337.         return(NULL);  /* illegal screen id */
  338.     }
  339.  
  340.     /* open window */
  341.      Wdw = (struct Window *)OpenWindow(&NewWdw);
  342.  
  343.     /* store window info */
  344.     if (Wdw)
  345.     {
  346.         /* global info */
  347.         Wdw_id        = id;
  348.         RPort        = Wdw->RPort;
  349.         fgdpen        = 1;
  350.         bgpen        = 0;
  351.  
  352.         if (Scrn == WBScrn)
  353.         {
  354.             WBWdw      = Wdw;
  355.             WBRPort     = RPort;
  356.             WBfgdpen = fgdpen;
  357.             WBbgpen     = bgpen;
  358.         }
  359.  
  360.         /* turtle graphics info */
  361.         tg_tx    = tg_initx;
  362.         tg_ty    = tg_inity;
  363.         tg_degs    = 270;
  364.         tg_pen    = 1;
  365.  
  366.         /* window list info */
  367.         StoreWdwInfo();    
  368.  
  369.         /* set IntuiMode */
  370.         IntuiMode = 1;
  371.  
  372.         /* set first drawing position */
  373.         Move(RPort,0,RPort->Font->tf_YSize - 2);
  374.         SetAPen(RPort,1L);
  375.     }
  376.  
  377.     if (Wdw == NULL) error_code = WINDOW_OPEN_ERR;
  378.  
  379.     return(Wdw);    /* NULL (error) or Wdw handle */
  380. }
  381.  
  382. void CloseWdw(window_id)
  383. ULONG  window_id;
  384. {
  385. /* close an Intuition window */
  386. USHORT id,n;
  387.  
  388.     id = (USHORT)window_id;
  389.  
  390.     if (id < 1 || id > MAXWDW-1 || Wdw_list[id].Wdw == NULL) return;
  391.  
  392.     /* close window */
  393.     ClearMenu();
  394.      if (Wdw_list[id].Wdw) CloseWindow(Wdw_list[id].Wdw);
  395.     
  396.     /* kill info about this window */
  397.     DeleteWdwInfo(window_id);
  398.  
  399.     /* find next highest numbered open window and make it active */
  400.     n=MAXWDW-1;
  401.     while (n > 0 && Wdw_list[n].Wdw == NULL) --n;
  402.  
  403.     Wdw_id = n;
  404.  
  405.     /* set the new current output window */
  406.     if (Wdw_list[Wdw_id].Wdw != NULL) MakeOutputWdw();     
  407.  
  408.     /* if Wdw-id=0 (shell) and only Wb screen -> IntuiMode OFF */
  409.     if (Wdw_id == 0 && Wdw_list[0].Wdw && Scrn == WBScrn) IntuiMode = 0;
  410. }
  411.  
  412. ULONG wdw_close_test(n)
  413. LONG n;
  414. {
  415. /* Test for selection of a window's close gadget. */
  416. BOOL      wdw_closegadget_clicked=FALSE;
  417. IntuiInfo *message;
  418. ULONG      MessageClass;
  419. ULONG      i;
  420.     
  421.     /* Test each user-defined window for a close-gadget click. 
  422.        If n=1 (compiler "-b" switch), close the window, otherwise 
  423.        make it the current output window so that the user-defined 
  424.        event trapping subroutine can call WINDOW(1) to close the 
  425.        window etc.
  426.         */
  427.  
  428.     /* GADGET WAIT trapped a CLOSEWINDOW? */
  429.     if (wdw_close_num >= 1 && wdw_close_num < MAXWDW)
  430.     {
  431.         if (n == 1) CloseWindow(Wdw_list[wdw_close_num].Wdw);
  432.         wdw_close_num=0;
  433.         return(1L);
  434.     }
  435.  
  436.     /* ON WINDOW? */
  437.     for (i=1;i<=MAXWDW-1 && !wdw_closegadget_clicked;i++)
  438.     {
  439.         if (Wdw_list[i].Wdw != NULL)
  440.            if ((message = 
  441.             GetIntuiEvent(Wdw_list[i].Wdw->UserPort)) != NULL)
  442.            {
  443.             MessageClass = message->Class;
  444.  
  445.             if (MessageClass & CLOSEWINDOW)    ClearIntuiEvent();
  446.  
  447.             if (MessageClass & CLOSEWINDOW)
  448.             {
  449.                 wdw_closegadget_clicked = TRUE;
  450.             
  451.                 if (n == 1)
  452.                 {
  453.                     /* close wdw before prg ends */
  454.                     CloseWindow(Wdw_list[i].Wdw);
  455.                 }
  456.                 else
  457.                 {
  458.                     /* make "close-gadget clicked" 
  459.                        window the current one */
  460.                     ChangeOutputWdw(i);
  461.                 }
  462.             }
  463.            }
  464.     }
  465.         
  466.     /* return 0 or 1 */
  467.     if (wdw_closegadget_clicked) 
  468.            return(1L);
  469.     else
  470.         return(0L);
  471. }
  472.  
  473. void set_wdw_close_num()
  474. {
  475. /* ON GADGET/MENU WAITing may get a CLOSEWINDOW message, 
  476.    so set a variable to indicate this. ON WINDOW trapping
  477.    will detect this and set the variable to 0 after 
  478.    returning a positive window-close event indication.
  479. */
  480.  
  481.     wdw_close_num = Wdw_id;
  482. }
  483.  
  484. LONG get_selected_wdw()
  485. {
  486. /*
  487. ** Return the window-id of the currently selected 
  488. ** window if it is an ACE window, otherwise zero.
  489. **
  490. ** Note that zero will also be returned if the shell
  491. ** is the currently selected window.
  492. */
  493. ULONG  ILock;
  494. struct Window *selected_wdw;
  495. LONG wdw_id = 0L;
  496. int i;
  497.  
  498.     ILock = LockIBase(0L);
  499.     selected_wdw = IntuitionBase->ActiveWindow;
  500.  
  501.     for (i=0;i<=MAXWDW-1;i++)
  502.         if (Wdw_list[i].Wdw == selected_wdw)
  503.         {
  504.         wdw_id = i;
  505.         break;
  506.         }    
  507.  
  508.     UnlockIBase(ILock);
  509.     
  510.     return(wdw_id);
  511. }
  512.